package com.mvp.lt.airlineview.record;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Binder;
import android.os.Build;
import android.os.Environment;
import android.os.HandlerThread;
import android.os.IBinder;
import androidx.core.app.NotificationCompat;
import android.text.TextUtils;
import android.view.Surface;


import com.mvp.lt.airlineview.App;
import com.mvp.lt.airlineview.R;
import com.mvp.lt.airlineview.record.event.RecordServiceEvent;
import com.mvp.lt.airlineview.record.event.RecordTimeEvent;
import com.mvp.lt.airlineview.utils.DateUtils;
import com.mvp.lt.airlineview.utils.FileUtils;
import com.mvp.lt.airlineview.utils.LogUtil;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;
import java.io.IOException;


/**
 * 录屏服务
 *
 * @author Liutao
 */

public class RecordService extends Service {
    private MediaProjectionManager projectionManager;
    private MediaProjection mediaProjection;
    private MediaRecorder mediaRecorder;
    private VirtualDisplay virtualDisplay;
    private boolean running;
    private boolean sAudio = false;
    //default size 720*1080
    private int width = 720;
    private int height = 1080;
    private int dpi;
    private String fileDir = "";
    private String dirPath = "";
    private String fileName = "";
    private String recordFilePath = "";
    private NotificationManager notificationManager;
    private Notification mNotification;
    private NotificationCompat.Builder mBuilder;
    public static String RecordScreenID = "1101";
    public static String RecordScreenChannelName = "RecordScreenChannelName";
    public void setProjectionManager(MediaProjectionManager projectionManager) {
        this.projectionManager = projectionManager;
    }

    @Override
    public IBinder onBind(Intent intent) {
        LogUtil.e("录屏服务", "===============onBind===========");
        return new RecordBinder();
    }

    @SuppressLint("NewApi")
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        LogUtil.e("录屏服务", "-------------onStartCommand--------------");
        createNotificationChannel();
        int mResultCode = intent.getIntExtra(ScreenRecorderUtils.RESULT_CODE, -1);
        Intent mResultData = intent.getParcelableExtra(ScreenRecorderUtils.RESULT_DATA);
        //mResultData = intent.getSelector();
        if (projectionManager == null) {
            projectionManager = (MediaProjectionManager) App.getContext().getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        }
        if (projectionManager != null) {
            mediaProjection = projectionManager.getMediaProjection(mResultCode, mResultData);
        }
        EventBus.getDefault().post(new RecordServiceEvent(startRecord()));
        return super.onStartCommand(intent, flags, startId);
    }

    private void createNotificationChannel() {

        notificationManager = (NotificationManager) App.getContext().getSystemService(NOTIFICATION_SERVICE);
        //前台服务notification适配
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(RecordScreenID, RecordScreenChannelName, NotificationManager.IMPORTANCE_HIGH);
            notificationManager.createNotificationChannel(channel);
        }
        //获取一个Notification构造器
        Intent nfIntent = new Intent(this, RecordServiceActivity.class);
        mBuilder = new NotificationCompat.Builder(this, RecordScreenID);
        mNotification = mBuilder.setContentTitle("正在录制视频")
                .setContentIntent(PendingIntent.getActivity(this, 0, nfIntent, 0))
                .setWhen(System.currentTimeMillis())
                .setContentText("00:00")
                .setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher_round))
                .setSmallIcon(R.mipmap.ic_launcher)
                .setAutoCancel(false)
                .setWhen(System.currentTimeMillis())
                .build();
        startForeground(1101, mNotification);
    }

    public void deleteNotification() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //关闭通知通道
            if (notificationManager != null) {
                notificationManager.deleteNotificationChannel(RecordScreenID);
            }
        } else {
            if (notificationManager != null) {
                notificationManager.cancel(1);
            }
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        EventBus.getDefault().register(this);
        HandlerThread serviceThread = new HandlerThread("service_thread", android.os.Process.THREAD_PRIORITY_BACKGROUND);
        serviceThread.start();
        LogUtil.e("录屏服务", "--------------onCreate-------------");
        running = false;
        mediaRecorder = new MediaRecorder();

    }

    @SuppressLint("NewApi")
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void OnRecordTimeEvent(RecordTimeEvent recordTimeEvent) {
        String time = DateUtils.getFormatHMS(recordTimeEvent.getTime());
        if (notificationManager != null && mNotification != null) {
            mBuilder.setContentTitle("正在录制视频");
            mBuilder.setContentText(time);
            mBuilder.setChannelId(RecordScreenID);
            notificationManager.notify(1101, mBuilder.build());
        }
    }

    @SuppressLint("NewApi")
    @Override
    public void onDestroy() {
        EventBus.getDefault().unregister(this);
        deleteNotification();
        running = false;
        try {
            if (mediaRecorder != null) {
                mediaRecorder.setOnErrorListener(null);
                mediaRecorder.setOnInfoListener(null);
                mediaRecorder.setPreviewDisplay(null);
                mediaRecorder.reset();
                mediaRecorder = null;
            }
            if (mediaRecorder != null) {
                try {
                    mediaRecorder.stop();
                } catch (IllegalStateException e) {
                    mediaRecorder = null;
                    mediaRecorder = new MediaRecorder();
                }
                mediaRecorder.release();
                mediaRecorder = null;
            }

        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
        try {
            if (virtualDisplay != null) {
                virtualDisplay.release();
                virtualDisplay = null;
            }
            if (mediaProjection != null) {
                mediaProjection.stop();
            }
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
        super.onDestroy();
    }

    @SuppressLint("NewApi")
    public boolean stopRecord() {
        deleteNotification();
        try {
            if (!running) {
                return false;
            }
            running = false;
            if (mediaRecorder != null) {
                mediaRecorder.setOnErrorListener(null);
                mediaRecorder.setOnInfoListener(null);
                mediaRecorder.setPreviewDisplay(null);
            }
            if (mediaRecorder != null) {
                try {
                    mediaRecorder.stop();
                } catch (IllegalStateException e) {
                    mediaRecorder = null;
                    mediaRecorder = new MediaRecorder();
                }
                mediaRecorder.reset();
            }
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
        try {
            if (virtualDisplay != null) {
                virtualDisplay.release();
            }
            if (mediaProjection != null) {
                mediaProjection.stop();
            }
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
        return true;

    }

    public boolean isRunning() {
        return running;
    }


    public void setConfig(int width, int height, int dpi) {
        this.width = width;
        this.height = height;
        this.dpi = dpi;
    }

    public boolean startRecord() {
        if (mediaProjection == null || running) {
            return false;
        }
        initRecorder();
        createVirtualDisplay();
        mediaRecorder.start();
        running = true;
        LogUtil.e("录屏服务", "-------startRecord----------");
        return true;
    }


    @SuppressLint("NewApi")
    private void createVirtualDisplay() {
        Surface surface = mediaRecorder.getSurface();
        virtualDisplay = mediaProjection.createVirtualDisplay("MainScreen", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, surface, null, null);
    }

    //自定义录像的宽高
    public void setRecorderConfig(int width, int height, String dirpath, String fileName, boolean audio) {
        LogUtil.e("录屏服务", "-------------onStartCommand--------------");
        if (width > 0 && height > 0) {
            this.width = width;
            this.height = height;
        }
        if (!TextUtils.isEmpty(dirpath)) {
            this.dirPath = dirpath;
        }
        if (!TextUtils.isEmpty(fileName)) {
            this.fileName = fileName;
        }
        this.sAudio = audio;
    }

    private void initRecorder() {
        if (mediaRecorder == null) {
            LogUtil.e("录屏服务", "==============mediaRecorder ==null===============");
            return;
        }
        try {
            if (!sAudio) {
                mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            }
            mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
//        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            if (TextUtils.isEmpty(fileName)) {
                recordFilePath = getsaveDirectory() + System.currentTimeMillis() + ".mp4";
            } else {
                recordFilePath = getsaveDirectory() + fileName + ".mp4";
            }
            LogUtil.e("录屏服务", "initRecorder:" + recordFilePath + "");
            mediaRecorder.setOutputFile(recordFilePath);
            mediaRecorder.setVideoSize(width, height);
            mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
            if (!sAudio) {
                mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            }
            mediaRecorder.setVideoEncodingBitRate((int) (width * height * 5));
            mediaRecorder.setVideoFrameRate(30);
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
        try {
            mediaRecorder.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String getsaveDirectory() {
        String rootDir;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            if (TextUtils.isEmpty(dirPath)) {
                rootDir = FileUtils.getDir("");
            } else {
                rootDir = dirPath;
            }

            File file = new File(rootDir);
            if (!file.exists()) {
                if (!file.mkdirs()) {
                    return null;
                }
            }
            return rootDir;
        } else {
            return null;
        }
    }

    public class RecordBinder extends Binder {
        public RecordService getRecordService() {
            return RecordService.this;
        }
    }

    public String getRecordFilePath() {
        return recordFilePath;
    }
}
